package space.xxhui.javatts.tts.reader.impl;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import space.xxhui.javatts.tts.reader.DictReader;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * @author HitvzByHui
 * date 2021-04-05
 */
@Component
public class CantoneseDictReader implements DictReader {

    private Logger logger = Logger.getAnonymousLogger();

    @Value("${tts.cantonese.spoken-dict}")
    private String spokenDictPath;//口语字典路径

    @Value("${tts.cantonese.stop-word-dict}")
    private String stopWordDictPath;//停顿词字典路径

    @Value("${tts.cantonese.word-file-map-dict}")
    private String wordFileMapDictPath;//词与语音匹配字典路径

    private Map<String, String> spokenDictMap = new HashMap<>();

    private Map<String, Integer> stopWordDictMap = new HashMap<>();

    private Map<String, String> wordFileMapDictMap = new HashMap<>();

    public boolean loadDict() {
        if (!loadSpokenDict()) {
            throw new RuntimeException("从路径" + spokenDictPath + "加载字典失败");
        }
        if (!loadStopWordDict()) {
            throw new RuntimeException("从路径" + stopWordDictPath + "加载字典失败");
        }
        if (!loadWordFileMapDictPath()) {
            throw new RuntimeException("从路径" + wordFileMapDictPath + "加载字典失败");
        }
        return true;
    }

    public boolean loadSpokenDict() {
        File spokenDictFile = new File(getAbsolutePath(spokenDictPath));
        if (spokenDictFile.isDirectory() || !spokenDictFile.exists()) {
            return false;
        }
        try {
            FileReader fileReader = new FileReader(spokenDictFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String record;
            //解析格式： 书面语词长度 词 词 词... 口语词长度 词 词 词...
            while ((record = bufferedReader.readLine()) != null) {
                if (record.contains("//")) {//去掉注释行
                    continue;
                }
                String[] dictRecord = record.split(" ");
                if (dictRecord.length == 1) {//没有空格的行也跳过
                    continue;
                }
                int writtenLanguageLength = Integer.parseInt(dictRecord[0]);
                if (writtenLanguageLength + 2 > dictRecord.length) {
                    logger.info("[" + record + "]行数据解析失败");
                }
                int spokenLanguageLength = Integer.parseInt(dictRecord[writtenLanguageLength + 1]);
                if (writtenLanguageLength + spokenLanguageLength + 2 > dictRecord.length) {
                    logger.info("[" + record + "]行数据解析失败");
                }
                StringBuilder formWordBuffer = new StringBuilder();
                for (int i = 1; i < writtenLanguageLength + 1; i++) {
                    formWordBuffer.append(dictRecord[i]).append("|");
                }
                StringBuilder toWordBuffer = new StringBuilder();
                for (int i = writtenLanguageLength + 2; i < writtenLanguageLength + spokenLanguageLength + 2; i++) {
                    toWordBuffer.append(dictRecord[i]).append("|");
                }
                spokenDictMap.put(formWordBuffer.toString(), toWordBuffer.toString());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    public boolean loadStopWordDict() {
        File stopWordDictFile = new File(getAbsolutePath(stopWordDictPath));
        if (stopWordDictFile.isDirectory() || !stopWordDictFile.exists()) {
            return false;
        }
        try {
            FileReader fileReader = new FileReader(stopWordDictFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String record;
            //解析格式： 词长度 词 词 词... 停顿时长权值
            while ((record = bufferedReader.readLine()) != null) {
                if (record.contains("//")) {//去掉注释行
                    continue;
                }
                String[] dictRecord = record.split(" ");
                if (dictRecord.length == 1) {//没有空格的行也跳过
                    continue;
                }
                int stopWordLength = Integer.parseInt(dictRecord[0]);
                if (stopWordLength + 2 > dictRecord.length) {
                    logger.info("[" + record + "]行数据解析失败");
                }
                int timeWeightValue = Integer.parseInt(dictRecord[stopWordLength + 1]);
                StringBuilder stopWordBuffer = new StringBuilder();
                for (int i = 1; i < stopWordLength + 1; i++) {
                    stopWordBuffer.append(dictRecord[i]).append("|");
                }
                stopWordDictMap.put(stopWordBuffer.toString(), timeWeightValue);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    public boolean loadWordFileMapDictPath() {
        File wordFileMapDictFile = new File(getAbsolutePath(wordFileMapDictPath));
        if (wordFileMapDictFile.isDirectory() || !wordFileMapDictFile.exists()) {
            return false;
        }
        try {
            FileReader fileReader = new FileReader(wordFileMapDictFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String record;
            //解析格式： 词 文件名 相关开头词个数
            while ((record = bufferedReader.readLine()) != null) {
                if (record.contains("//")) {//去掉注释行
                    continue;
                }
                String[] dictRecord = record.split(" ");
                if (dictRecord.length == 1) {//没有空格的行也跳过
                    continue;
                }
                if (dictRecord.length > 3) {
                    logger.info("[" + record + "]行数据解析失败");
                }
                String wordAscIICode = dictRecord[0] + "|";
                String fileName = dictRecord[1];
                Integer sentenceCount = Integer.parseInt(dictRecord[2]);
                wordFileMapDictMap.put(wordAscIICode, fileName);
                if (sentenceCount > 0) {
                    for (int i = 0; i < sentenceCount; i++) {
                        String sentenceRecord = bufferedReader.readLine();
                        String[] dictSentenceRecord = sentenceRecord.split(" ");
                        if (dictSentenceRecord.length == 1) {//没有空格的行也跳过
                            continue;
                        }
                        Integer wordCount = Integer.valueOf(dictSentenceRecord[0]);
                        if (wordCount * 2 + 1 > dictSentenceRecord.length) {
                            logger.info("[" + dictSentenceRecord + "]行数据解析失败");
                        }
                        StringBuilder sentenceAscIICodeListSb = new StringBuilder();
                        StringBuilder sentenceFileNameListSb = new StringBuilder();
                        for (int j = 1; j < wordCount * 2 + 1; j++) {
                            if (j % 2 == 1) {
                                sentenceAscIICodeListSb.append(dictSentenceRecord[j]).append("|");
                            } else {
                                sentenceFileNameListSb.append(dictSentenceRecord[j]).append("|");
                            }
                        }
                        wordFileMapDictMap.put(sentenceAscIICodeListSb.toString(), sentenceFileNameListSb.toString());
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    public String getAbsolutePath(String relativePath) {
        String path = "";
        try {
            path = ResourceUtils.getURL(relativePath).getPath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return path;
    }


}
